package Master;

import java.util.LinkedList;
import java.util.Queue;

/**
 * Project:    metsysdirg
 * File Name: ScheduleAlgorithm.java
 * Change History:
 *     ********************************
 *     1.0     5/14/2011    Hengfeng Li
 *         Create the skeleton file
 *     ********************************
 *
 */
public class ScheduleAlgorithm {
    /*

     Becase we now just adopt a FCFS strategy, so
     there is no thing in ScheduleAlgorithm. But at
     the advanced version, we need implement a priority
     queue according to the cost and time of the task

     */
	/*public static enum AlgorithmFlag {FCFS, COST, TIME};*/
	public static enum CompareFactor {cost, time};
	public static CompareFactor compareFactor = CompareFactor.cost;
    
	public ScheduleAlgorithm(){

    }
    
    public void costBasedSchedule(TaskPlan taskPlan){
        // this.taskPlan = taskPlan;
        Queue<Task> taskQueue = new LinkedList<Task>();
        Task firstTask;

        if(taskPlan==null)
    	{
    		System.out.println("Error: The task plan is null");
    		return;
    	}

        
        for(Task task : taskPlan.getTasks()){
            //System.out.println("task ID" + task.getTaskID());
        	taskQueue.offer(task);
        }

        // 1. Sort resources by increasing cost
        taskPlan.sortResources();

        // 2. For each resource in order, assign as many as jobs as possible to the resource.
        //    without exceeding the deadline

        for(Resource resource : taskPlan.getResources()){

            if(resource.isAvailable()){

                firstTask = taskQueue.peek();

                while(firstTask != null
                        && (firstTask.getEstimateTime()
                        + resource.getNextCompleteTime() < taskPlan.getTimeRequired())) {
                    firstTask = taskQueue.poll();
                    resource.addTask(firstTask);
                    if(taskQueue.size() != 0){
                        firstTask = taskQueue.peek();
                    } else {
                        break;
                    }

                }
            }
        }
        // 3. Repeat all steps until all jobs are proceed

        if( taskQueue.size() != 0) {
            // cost optimize method can not be finished before
            // deadline
        }

        
    }
    
    public void timeBasedSchedule(TaskPlan taskPlan){
    	
    	Queue<Task> taskQueue = new LinkedList<Task>();
    	float currentTime, nextCompTime;
    	Resource resource;

        if(taskPlan==null)
    	{
    		System.out.println("Error: The task plan is null");
    		return;
    	}
        
        for(Task task : taskPlan.getTasks()){
            //System.out.println("task ID" + task.getTaskID());
        	taskQueue.offer(task);
        }
		
        for( Task task : taskPlan.getTasks()){
        	compareFactor = CompareFactor.cost;
        	taskPlan.sortResources();
        	compareFactor = CompareFactor.time;
        	taskPlan.sortResources();
        	
        	currentTime = task.getEstimateTime();
        	resource = taskPlan.getFirstResource();
        	nextCompTime = resource.getNextCompleteTime();
        	nextCompTime += currentTime;
        	
        	if(nextCompTime > taskPlan.getTimeRequired()){
        		System.out.println("NOT Feasible!");
        		break;
        	}
        	else{
        		resource.addTask(task);
        	}
        }        
    }
    
    public void fcfsBasedSchedule(TaskPlan taskPlan){

        System.out.println("TaskPlan's tasks size :::::" + taskPlan.getTasks().size());

    	Queue<Task> taskQueue = new LinkedList<Task>();
    	float currentTime, nextCompTime;
    	Resource resource;

        if(taskPlan==null)
    	{
    		System.out.println("Error: The task plan is null");
    		return;
    	}
        
        for(Task task : taskPlan.getTasks()){
            //System.out.println("task ID" + task.getTaskID());
            System.out.println("New Task "+ task.getTaskID());
        	taskQueue.offer(task);

        }

        System.out.println("Task Queue size :::" + taskQueue.size());
		
        for( Task task : taskPlan.getTasks()){
        	compareFactor = CompareFactor.time;
        	taskPlan.sortResources();
        	
        	currentTime = task.getEstimateTime();
        	resource = taskPlan.getFirstResource();
        	nextCompTime = resource.getNextCompleteTime();
        	nextCompTime += currentTime;
        	
        	if(nextCompTime > taskPlan.getTimeRequired()){
        		System.out.println("NOT Feasible!");
        		break;
        	}
        	else{
        		resource.addTask(task);
        	}
        }        
    }
    
    
    
    
    
}
